package variabilitysmelldetection.measurement.measures.component;

import java.util.List;
import java.util.StringTokenizer;

import variabilitysmelldetection.measurement.measures.Measure;
import variabilitysmelldetection.measurement.models.ComponentItem;
import variabilitysmelldetection.measurement.models.Item;



public class LinesOfCode extends Measure {

	public LinesOfCode() {
		super("Lines of Code", "LoC");
	}

	public LinesOfCode(String name, String acronym){
		super(name, acronym);
	}

	@Override
	public void measure(List<ComponentItem> items) {
		for (ComponentItem classe : items) {
			measure(classe);
		}
	}	
	
	private void measure(Item item) {
		double value = calculateLines(item.getSource());
		setValue(value);
		
		LinesOfCode linesOfCode = new LinesOfCode();
		linesOfCode.setValue(value);
		item.addMeasure(linesOfCode);
		
	}
	
	
	/**
	 * Copy from Metrics
	 * http://metrics.cvs.sourceforge.net/viewvc/metrics/net.sourceforge.metrics/src/net/sourceforge/metrics/calculators/LinesOfCode.java?revision=1.13&view=markup
	 * @param source
	 * @return
	 */
	protected int calculateLines(String source) {
		int total = 0;
		int firstCurly = source.indexOf('{');
		if (firstCurly != -1) {
			String body = source.substring(firstCurly+1, source.length()-1).trim();
			StringTokenizer lines = new StringTokenizer(body, "\n");
			while(lines.hasMoreTokens()) {
				String trimmed = lines.nextToken().trim();
				if (trimmed.length() == 0) {
					continue;
				}
				
				if (trimmed.startsWith("/*")) {
					while (trimmed.indexOf("*/") == -1) {
						trimmed = lines.nextToken().trim();
					}
					if (lines.hasMoreTokens()) {
						trimmed = lines.nextToken().trim();
					}
				}
				if (!trimmed.startsWith("//")) {
					total++;
				}
			}
		}
		return total;
	}
}
